#pragma once

#include <string>
#include <memory>
#include <spdlog/spdlog.h>
#include <spdlog/fmt/fmt.h>
#include <nlohmann/json.hpp>

namespace leomedlog {

struct LogConfig {
    std::string app_name;
    std::string log_dir = "logs";
    std::string crash_dir = "crashes";
    std::string sentry_dsn; // Empty = Local Dump only
    int max_files = 10;
    int max_file_size_mb = 100;
};

// Initialize the logging system. Aborts on failure.
void Init(const LogConfig& config);

// Shutdown and flush logs.
void Shutdown();

// Internal accessor, but public for macros
std::shared_ptr<spdlog::logger> GetLogger();

// Internal helper for structured logging
inline std::string FormatKV(const std::string& msg, const nlohmann::json& j) {
    return fmt::format("{}|||JSON|||{}", msg, j.dump());
}

} // namespace leomedlog

// -----------------------------------------------------------------------------
// Macros
// -----------------------------------------------------------------------------

// Basic Logging
#define LEO_LOG_TRACE(...) leomedlog::GetLogger()->trace(__VA_ARGS__)
#define LEO_LOG_DEBUG(...) leomedlog::GetLogger()->debug(__VA_ARGS__)
#define LEO_LOG_INFO(...)  leomedlog::GetLogger()->info(__VA_ARGS__)
#define LEO_LOG_WARN(...)  leomedlog::GetLogger()->warn(__VA_ARGS__)
#define LEO_LOG_ERROR(...) leomedlog::GetLogger()->error(__VA_ARGS__)
#define LEO_LOG_CRITICAL(...) leomedlog::GetLogger()->critical(__VA_ARGS__)

// Structured Logging
// Usage: LEO_LOG_INFO_KV("User login", {"uid", 123}, {"ip", "127.0.0.1"});
#define LEO_LOG_INFO_KV(msg, ...) \
    leomedlog::GetLogger()->info("{}|||JSON|||{}", msg, nlohmann::json{__VA_ARGS__}.dump())

#define LEO_LOG_WARN_KV(msg, ...) \
    leomedlog::GetLogger()->warn("{}|||JSON|||{}", msg, nlohmann::json{__VA_ARGS__}.dump())

#define LEO_LOG_ERROR_KV(msg, ...) \
    leomedlog::GetLogger()->error("{}|||JSON|||{}", msg, nlohmann::json{__VA_ARGS__}.dump())

